package thread.sync.interference;
import static java.lang.System.out;

public class XYZ implements Runnable{
	static int x = 0 , y = 0, z = 0;
	
	public static void main(String[] args) throws InterruptedException{
		
		new Thread(new XYZ()).start();
		new Thread(new XYZ()).start();
	}
	
	@Override
    public void run() {
		process1();
		//process2();
		//process3();
	}
	
	static void process1(){
		for (int i=0; i < 100; i++) {
			x++;
			delay();
			y = y + x;
			delay();
			z = z + y;
		}
		out.println("z = " + z);
	}
	
	static synchronized void process2(){
		for (int i=0; i < 100; i++) {
			x++;
			delay();
			y = y + x;
			delay();
			z = z + y;
		}
		System.out.println("z = " + z);
	}
	
	static void process3(){
		// synchronizing a class means all static data will be locked for each thread.
		synchronized(XYZ.class){
			for (int i=0; i < 100; i++) {
				x++;
				delay();
				y = y + x;
				delay();
				z = z + y;
			}
			out.println("z = " + z);
		}
	}
	
	static void delay(){
		for (double d = 0; d < 1000000; d++) {
			; // A way to delay without sleep, sleep will die this thread for n seconds
		}
	}
}

// No Synch version - process1, result may vary in each run
/*
z = 1293800
z = 1373400

z = 1313346
z = 1373347

z = 1333200
z = 1373398
*/

// synchronized method - process 2, Same result in every run
/*
z = 171700
z = 1353400
*/

// XYZ.class - process 3, Same result in every run
/*
z = 171700
z = 1353400
 */

